<?php

namespace App\Http\Model;

use App\Http\Services\Meeting\MeetingServices;
use App\Lib\Search;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Ramsey\Uuid\Uuid;


class User extends Base
{
    public $table = 'user';
    protected $photoTable = 'user_photo';
    protected $feedbackTable = 'user_feedback';
    protected $deviceRiskTable = 'device_risk';
    protected $rechargeLimitTable = 'user_recharge_limit';
    protected $defaultPortraitTable = 'default_portrait';
    protected $userRemarkTable = 'user_remark';
    protected $userTagsTable = 'user_tags';
    protected $userTagsCatTable = 'user_tags_cat';
    protected $userMicroBlockLogTable = 'user_micro_block_log';
    protected $user_noinvite_table = "user_noinvite";
    protected $chat_friend_baseinfo_table = 'chat_friend_baseinfo';//用户审核资料表
    protected $userMsgTable = 'user_msg';//用户每日聊天条数记录
    protected $userExcelLogTable = 'user_excel_log';//用户每日聊天条数记录


    public $timestamps = false;

    //token缓存键
    private $redis_cache_user_token_key = 'CACHE:USER:TOKEN:'; //CACHE:USER:TOKEN:{token}
    //用户缓存键
    private $redis_cache_user_key = 'CACHE:USER:'; //CACHE:USER:{user_id}
    //用户反查token hash
    private $redis_cache_user_token_hash = "CACHE:USER:TOKEN:HASH";

    private $redis_user_uid_generated_db = "USER:UID:GENERATED:DB";

    private $redis_user_remain_room = 'CACHE:USER:ROOM:';
    private $user_remain_room_time = 1*60;

    private $userOnlineMap = 'USER:ONLINE';
    private $userOnlineWomanMap = 'USER:ONLINE:WOMAN';
    private $userOnlineManMap = 'USER:ONLINE:MAN';
    private $redis_user_device_token_key = 'USER:DEVICE:TOKEN';
    protected $smsPrefix = 'sms_';
    protected $userAccountCancel = 'USER:ACCOUNT:CANCEL'; //用户注销申请列表
    protected $userAccountCancelData = 'USER:ACCOUNT:CANCEL:DATA'; //用户注销申请数据列表

    private $userCallPool = 'USER:CALL:POLL';
    protected $redis_user_gift_switch = 'USER:GIFT:SWITCH';
    protected $redis_test_user_ids = 'CACHE:TEST:USERS';
    protected $redis_micro_block = 'USER:MICRO_BLOCK:%s'; //用户禁麦缓存
    
    private $userActiveSet = 'USER:ACTIVE:';//用户活跃 USER:ACTIVE:{Ymd}=>{user_id}


    //access_token redis 缓存前缀
    const THIRD_COOPERATE_REDIS_PRE = 'THIRD:COOPERATE:';
    const THIRD_COOPERATE_EXPIRE = 86400 * 30;

    const RONG_CLOUD_TOKEN_REDIS_PRE = 'RONG:CLOUD:TOKEN:';//融云token string
    const RONG_CLOUD_TOKEN_EXPIRE_TIME = 86400 * 30;//融云token过期时间
    //未实名用户已经充值金额
    const NO_REAL_NAME_RECHARGE_TOTAL_NUM = 'NO:REAL:TOTAL:RECHARGE:NUM:'; //string NO:REAL:TOTAL:RECHARGE:NUM:{user_id}
    //未实名用户今日已经充值金额
    const NO_REAL_NAME_RECHARGE_DAY_NUM = 'NO:REAL:DAY:RECHARGE:NUM:'; //string NO:REAL:DAY:RECHARGE:NUM:{user_id}:ymd
    //日限额 200rmb
    const NO_REAL_NAME_RECHARGE_DAY_LIMIT = 20000;
    //未实名总限额 1000rmb
    const NO_REAL_NAME_RECHARGE_MAX_LIMIT = 100000;

    //sql查询键
    private $sql_user_fields = [
        'user.user_id as user_id','user.mobile_phone as phone',
        'user.uuid as user_uid','user.nickname as nickname',
        'user.birthday as birthday','user.affective_state as affective_state','user.gender as gender',
        'user.sign as sign','user.province as province','user.occupation as occupation',
        'user.school as school','user.province as province','user.city as city','user.portrait as portrait','user.active_certify as active_certify','user.code as code','user.guid as guid', 'user.channel_id as channel_id',
        'user.liang as liang',
        'user.super as super',
        'user.official as official',
        'user.waiter as waiter',
        'user.create_timestamp as create_timestamp',
        'user.invite_uid as invite_uid',
        'user.v as v',
        'user.v_desc as v_desc',
        'user.is_abnormal as is_abnormal',
        'user.voice as voice', 'user.voice_time as voice_time',
        'user.cp_status as cp_status',
        'user.is_open_code as is_open_code',
        'user.is_visitor as is_visitor',
        'user.union_vest as union_vest',
        'user.union_vest_switch  as union_vest_switch',
        'user.height as height',
        'user.tags as tags',
        'user.other_tags as other_tags',
        'user.mood_id as mood_id',
        'user.identity_role as identity_role',
	'user.identity_status as identity_status',
	'user.is_open_code as is_open_code',
	'user.invite_uid_new as invite_uid_new',
    ];

    private $redis_user_uid_index = "USER:UID:INDEX";
    private $redis_user_uid_lianghao = "USER:UID:LIANGHAO";
    private $redis_user_forbid_key = "CACHE:FORBID:USER";
    private $redis_device_forbid_key = "CACHE:FORBID:DEVICE";
    private $redis_forbid_ip = 'CACHE:FORBID:IP:';

    private $token_name = "user_token";
    private $noviceTimes = 3600*24*7; // 萌新时间改为7天
    private $oldUserTimes = 7 *24 * 60 * 60;

    const USER_DEFAULT_IMAGE = ["http://ccoss.yinlaiwlkj.top/portrait/atm.png"];

    protected $userSetTable = 'user_set';
    private $redis_user_set_key = "CACHE:USER:SET:";
    protected $userYearReportCacheKey = 'USER:YEAR:REPORT:CACHE'; //用户注销申请数据列表
    protected $userFalseMobile = 'USER:FALSE:MOBILE';

    private $userToken = '';// 当前设置的用户token值
    protected $adapt_size ;

    protected $redis_user_remark = 'USER:REMARK:';

    //用户融云token
    protected $userRongTokenKey = 'CACHE:USER:RONGTOKEN:';//string CACHE:USER:RONGTOKEN:{user_id} => {string}

    //用户tdid缓存
    protected $userTdidKey = 'CACHE:USER:TDID';//hash CACHE:USER:TDID {user_id}=>{string}

    public function __construct(array $attributes = [])
    {
        parent::__construct($this->table, $attributes);
        $adapters = explode(',',Redis::HGET('IMAGE:ADAPT' ,'user'));
        $this->adapt_size = !empty($adapters) && count($adapters)>1 ? $adapters[1] : 480;
    }

    /**
     * 添加用户
     *
     * @param string $mobilePhone 手机号
     * @param string $password 密码
     * @param int $inviteUserId 邀请人user_id
     * @param int $isVisitor 是否游客（0=否，1=是）
     * @param string $nickname 用户昵称
     * @param string $image 用户头像
     * @return int
     */
    public function create($mobilePhone, $password = '', $inviteUserId = 0, $isVisitor = 0, $nickname = '', $image = '', $inviteUserIdNew = 0)
    {
        if ($isVisitor == 0) {
            $uuid = $this->generated_uid();
            if (empty($uuid)) {
                return false;
            }
        } else {
            $uuid = $mobilePhone;
            $password = '';
        }

        $data = [
            'mobile_phone' => $mobilePhone,
            'password' => $password,
            'uuid' => $uuid,
            'create_timestamp' => time(),
            'is_visitor' => $isVisitor,
        ];

        // TODO 邀请人的用户ID
        if (!empty($inviteUserId)) {
            $data['invite_uid'] = $inviteUserId;
        }
        if (!empty($inviteUserIdNew)) {
            $data['invite_uid_new'] = $inviteUserIdNew;
        }
        if (!empty($nickname)) {
            $data['nickname'] = $nickname;
        }
        if (!empty($image)) {
            // 处理资源域
            $appPicDomain = parse_url(getPicDomain(), PHP_URL_HOST);
            $parseUrlImg = parse_url($image);
            if (isset($parseUrlImg['path']) and isset($parseUrlImg['host']) and $appPicDomain == $parseUrlImg['host']) {
                $data['portrait'] = json_encode([$parseUrlImg['path']], JSON_UNESCAPED_UNICODE);
            } else {
                $data['portrait'] = json_encode([$image], JSON_UNESCAPED_UNICODE);
            }
        }
        // 创建用户数据
        $userId = DB::table($this->table)->insertGetId($data);

        // 更新推荐码
        $code = createCode($userId);
        DB::table($this->table)->where(['user_id' => $userId])->update(['code' => $code]);

        return $userId;
    }


    /**
     * 编辑用户信息
     * @param $user_id
     * @param $home
     * @param $nickname
     * @param $gender
     * @param $birthday
     * @param $images
     * @param $affective_state
     * @param $occupation
     * @param $school
     * @param $sign
     * @return int
     */
    public function edit($user_id, $home, $nickname, $gender, $birthday, $images, $affective_state, $occupation, $school, $sign, $voice = null, $voice_time = 0, $inviteUserId = 0,$vest_switch= -1, int $height = 0, $mood_id = 0, $identity_role = 0, $identity_status = 0, $inviteUserIdNew = 0){
        $this->del_cache_user($user_id);
        $data = [];
        if (!empty($home)){
            $tmp = explode('#',$home);
            if(isset($tmp[0]) && isset($tmp[1])){
                $data['province'] = $tmp[0];
                $data['city'] = $tmp[1];
            }
        }
        if (!empty($nickname)){
            $data['nickname'] = $nickname;
        }

        if (!empty($gender)){
            $data['gender'] = $gender;
        }

        if (!empty($birthday)){
            $data['birthday'] = $birthday;
        }

        if (!empty($images)){
            $pic_host = parse_url(getPicDomain(), PHP_URL_HOST);
            $tempImgs = explode(',',$images);
            $list_image = [];
            foreach($tempImgs as $k => $v){
                $tempArr = parse_url($v);
                if(isset($tempArr['path']) && isset($tempArr['host'])){
                    if ($pic_host == $tempArr['host']){
                        $list_image[] = $tempArr['path'];
                    }
                    else{
                        $list_image[] = $v;
                    }

                }
            }
            $list_image = array_values(array_unique($list_image));
            $data['portrait'] = json_encode($list_image);
        }

        if (!empty($affective_state)){
            $data['affective_state'] = $affective_state;
        }

        if (!empty($occupation)){
            $data['occupation'] = $occupation;
        }

        if (!empty($school)){
            $data['school'] = $school;
        }

        if (!empty($sign)){
            $data['sign'] = $sign;
        }

        if (!empty($voice_time)){
            $data['voice_time'] = intval($voice_time);
        }

        if (!empty($voice)){
            $voiceInfo = parse_url($voice);
            $data['voice'] = (isset($voiceInfo['path']) && isset($voiceInfo['host'])) ? $voiceInfo['path'] : "";
        }
        if ($voice === "") {
            $data['voice'] = "";
            $data['voice_time'] = 0;
        }

        if ($inviteUserId) {
            $data['invite_uid'] = $inviteUserId;
        }
        if ($inviteUserIdNew) {
            $data['invite_uid_new'] = $inviteUserIdNew;
        }
        if($vest_switch >=0){
            $data['union_vest_switch'] = $vest_switch;
        }
        if($height) {
            $data['height'] = $height;
        }
        if($mood_id) {
            $data['mood_id'] = $mood_id;
        }
        if($identity_role) {
            $data['identity_role'] = $identity_role;
        }
        if($identity_status) {
            $data['identity_status'] = $identity_status;
        }
        if(empty($data)) {
            return 1;
        }
        
        $result = DB::table("user")
            ->where("user_id", "=", $user_id)
            ->update($data);
        return $result;


    }

    //交友资料审核
    public function chat_friend_base_info($images, $user_id, $voice, $sign, $user, $chat_sign){
        if(!empty($images)){
            $images = explode(',',$images);
            $images = array_filter($images);
            $imageInfo = parse_url(end($images));
            $insert['image'] = (isset($imageInfo['path']) && isset($imageInfo['host'])) ? $imageInfo['path'] : "";
        }
        if (!empty($voice)){
            $voiceInfo = parse_url($voice);
            $insert['voice'] = (isset($voiceInfo['path']) && isset($voiceInfo['host'])) ? $voiceInfo['path'] : "";
        }
        //交友资料审核表
        $isset = DB::table($this->chat_friend_baseinfo_table)->where('user_id',$user_id)->first();
        $isset = self::objToArray($isset);
        $insert['sign'] = empty($sign) ? $user['sign'] : $sign;//个性签名
        $insert['user_id'] = $user_id;//用户id
        $insert['status'] = 0;//0=审核中 1=审核通过 2审核驳回
        if(empty($chat_sign) && !empty($isset['chat_sign'])){
            $chat_sign = $isset['chat_sign'];
        }
        $insert['chat_sign'] = empty($chat_sign) ? '' : $chat_sign;
        if($isset){
            DB::table($this->chat_friend_baseinfo_table)->where('user_id',$user_id)->update($insert);
        }else{
            DB::table($this->chat_friend_baseinfo_table)->insert($insert);
}
    }
    /**
     * 设置密码
     * @param $user_id
     * @param $password
     * @return int
     */
    public function set_password($user_id, $password){
        $result = DB::table("user")
            ->where("user_id", "=", $user_id)
            ->update(['password' => $password]);
        return $result;
    }


    /**
     * 设置用户手机号
     * @param $user_id
     * @param $phone
     * @return int
     */
    public function set_phone($user_id, $phone){
        $this->del_cache_user($user_id);
        $result = DB::table("user")
            ->where("user_id", "=", $user_id)
            ->update(['mobile_phone' => $phone]);
        return $result;
    }


    /**
     * 设置token
     * @param $user_id
     * @param $token
     * @param $expire
     * @return int
     */
    public function set_token($user_id, $token, $expire){
        $result = DB::table("user")
            ->where("user_id", "=", $user_id)
            ->update(['token' => $token, 'expire_time' => time() + $expire]);
        return $result;
    }

    /**
     * 获取用户密码信息
     * @param $phone
     * @return mixed|null
     */
    public function get_password_by_phone($phone){
        $users = DB::table("user")
            ->where("mobile_phone", "=", strval($phone))
            ->first(['user_id','password']);
        $result = self::objToArray($users);
        if (empty($result)){
            return null;
        }

        return $result;
    }

    /**
     * 设置游客用户手机号
     * @param $userId
     * @param $phone
     * @return int
     */
    public function modifyVisitorPhone($userId, $phone)
    {
        $uuid = $this->generated_uid();
        if (empty($uuid)) {
            return false;
        }

        $this->del_cache_user($userId);
        return DB::table('user')
            ->where(['user_id' => $userId, 'is_visitor' => 1])
            ->update(['mobile_phone' => $phone, 'uuid' => $uuid, 'is_visitor' => 0]);
    }

    /**
     * 获取密码
     * @param $user_id
     * @return mixed|null
     */
    public function get_password($user_id){
        $users = DB::table("user")
            ->where("user_id", "=", $user_id)
            ->first(['user_id', 'password']);
        $result = self::objToArray($users);
        if (empty($result)){
            return null;
        }
        return $result;
    }


    /**
     * 判断昵称是否存在 排除当前用户ID
     * @param $nickname
     * @param $user_id
     * @return bool
     */
    public function check_exist($nickname, $user_id){
        $result = DB::table("user")
            ->where("nickname", "=", $nickname)
            ->first(['user_id']);
        if (empty($result)){
            return false;
        }
        $result = self::objToArray($result);
        if ($result['user_id'] == $user_id){
            return false;
        }
        return true;
    }


    /**
     * 获取用户列表 by ids
     * @param $id_arr
     * @return mixed
     */
//    public function get_users_by_ids($id_arr){
//        $ret_data = [];
//        $no_cache_id_arr = [];
//        for ($i = 0; $i < count($id_arr); $i++){
//            $user_item = $this->get_cache_user(intval($id_arr[$i]));
//            if ($user_item != null){
//                // 获取到缓存数据
//                array_push($ret_data, $user_item);
//            }
//            else{
//                // 未命中缓存的用户ID
//                array_push($no_cache_id_arr, intval($id_arr[$i]));
//            }
//        }
//
//        // 查询未命中缓存用户
//        $users = DB::table("user")->whereIn("user_id", $no_cache_id_arr)
//            ->get($this->sql_user_fields);
//        $result = self::objToArray($users);
//
//        for ($i = 0; $i < count($result); $i++){
//            if(!empty($result[$i]['province']) && !empty($result[$i]['city'])){
//                $result[$i]['home'] = $result[$i]['province'].'#'.$result[$i]['city'];
//            }else{
//                $result[$i]['home'] = '';
//            }
//            $result[$i]['images'] = $this->build_images($result[$i]['portrait']);
//            unset($result[$i]['portrait']);
//            unset($result[$i]['province']);
//            unset($result[$i]['city']);
//            $this->set_cache_user(intval($result[$i]['user_id']), $result[$i]);
//            unset($result[$i]['phone']);
//            // 添加到返回列表
//            array_push($ret_data, $result[$i]);
//            // 设置用户缓存
//        }
//        return $ret_data;
//    }

    public function get_users_by_ids($id_arr){
        if (empty($id_arr)){
            return [];
        }
        $user_in_cache = Redis::MGET(array_map(function ($user_id){
            return $this->redis_cache_user_key. $user_id;
        }, $id_arr));

        $user_in_cache = array_map(function ($user){
            return json_decode($user, true);
        }, array_filter($user_in_cache));

        $result = [];
        if(!empty($user_not_in_cache = array_diff_key($id_arr,$user_in_cache))){
            // 查询未命中缓存用户
            $users = DB::table("user")->whereIn("user_id", $user_not_in_cache)
                ->get($this->sql_user_fields);
            $result = self::objToArray($users);
            $now = time();
            $search = new Search();
            foreach ($result as $key => &$user) {
                if(!empty($user['union_vest']) && $user['union_vest_switch'] ==1){
                    $user['nickname'] = $user['union_vest'].'·'.$user['nickname'];
                }
                if(!empty($user['province']) && !empty($user['city'])){
                    $user['home'] = $user['province'].'#'.$user['city'];
                }else{
                    $user['home'] = '';
                }
                $user['novice'] = 0;
                if (isset($user['create_timestamp']) && $now - intval($user['create_timestamp']) < $this->noviceTimes){
                    $user['novice'] = 1;
                }
                //图片尺寸适配
                $images_arr = json_decode($user['portrait'],true) ?? [];
                $user['adapt_images'] = empty($images_arr) ? [] : build_adapt_images($images_arr ,$this->adapt_size);

                $user['images'] = $this->build_images($user['portrait']);
                $user['thumbnails'] = $this->build_thumbnails($user['portrait']);
                $user['voice'] = $this->build_voice($user['voice']);
//                unset($user['portrait'], $user['province'], $user['city'], $user['create_timestamp']);
                unset($user['portrait'], $user['province'], $user['city']);
                // write_log("search", "indexUser-user-1", $user);
                $search->indexUser($user);
                $this->set_cache_user(intval($user['user_id']), $user);
            }
            unset($user);
        }
        $retData = array_merge($user_in_cache, $result);

        foreach ($retData as $k => $v){
            $retData[$k]['tags'] = isset($retData[$k]['tags']) && $retData[$k]['tags'] ? json_decode($retData[$k]['tags'], true) : [];
            $retData[$k]['other_tags'] = isset($retData[$k]['other_tags']) && $retData[$k]['other_tags'] ? json_decode($retData[$k]['other_tags'], true) : [];
            unset($retData[$k]['phone']);
        }
        return $retData;
    }

    /**
     * 通过用户id获取手机号
     *
     * @param [int] $userid
     * @return void
     */
    public function get_user_phone($userid)
    {
        $users = DB::table("user")
            ->where("user_id",$userid)
            ->first(['mobile_phone']);
        $result = self::objToArray($users);
        return $result;
    }

    /**
     * 获取用户信息 电话号
     * @param $phone
     * @return mixed
     */
    public function get_user_by_phone($phone){

        // 关系数据库读取
        $users = DB::table("user")
            ->where("mobile_phone", "=", strval($phone))
            ->first($this->sql_user_fields);
        $result = self::objToArray($users);

        if(!empty($result)){
            if(!empty($result['union_vest']) && $result['union_vest_switch'] ==1){
                $result['nickname'] = $result['union_vest'].'·'.$result['nickname'];
            }
            if(!empty($result['province']) && !empty($result['city'])){
                $result['home'] = $result['province'].'#'.$result['city'];
            }else{
                $result['home'] = '';
            }
            //图片尺寸适配
            $images_arr = json_decode($result['portrait'],true) ?? [];
            $result['adapt_images'] = empty($images_arr) ? [] : build_adapt_images($images_arr ,$this->adapt_size);

            $result['images'] = $this->build_images($result['portrait']);
            $result['thumbnails'] = $this->build_thumbnails($result['portrait']);
            $now = time();
            $result['novice'] = 0;
            if (isset($result['create_timestamp']) && $now - intval($result['create_timestamp']) < $this->noviceTimes){
                $result['novice'] = 1;
            }
            
            $result['tags'] = $result['tags'] ? json_decode($result['tags'], true) : [];
            $result['other_tags'] = $result['other_tags'] ? json_decode($result['other_tags'], true) : [];
            unset($result['create_timestamp']);
            unset($result['portrait']);
            unset($result['province']);
            unset($result['city']);
            unset($result['phone']);
        }
        // 设置缓存
        if(empty($result)){
            return null;
        }
        return $result;
    }

    /**
     * 通过用户id获取首冲礼包显示状态
     *
     * @param [int] $userid
     * @return void
     */
    public function get_user_first_recharge($userid)
    {
        $users = DB::table("user")
            ->where("user_id",$userid)
            ->first(['first_recharge_status']);
        $result = self::objToArray($users);
        return $result;
    }


    /**
     * 通过邀请Code获取用户
     * @param $code
     * @return mixed|null
     */
    public function getUserByCode($code){

        // 关系数据库读取
        $users = DB::table("user")
            ->where("code", "=", strval($code))
            ->first($this->sql_user_fields);
        $result = self::objToArray($users);

        if(!empty($result)){
            if(!empty($result['union_vest']) && $result['union_vest_switch'] ==1){
                $result['nickname'] = $result['union_vest'].'·'.$result['nickname'];
            }
            if(!empty($result['province']) && !empty($result['city'])){
                $result['home'] = $result['province'].'#'.$result['city'];
            }else{
                $result['home'] = '';
            }
            //图片尺寸适配
            $images_arr = json_decode($result['portrait'],true) ?? [];
            $result['adapt_images'] = empty($images_arr) ? [] :  build_adapt_images($images_arr ,$this->adapt_size);

            $result['images'] = $this->build_images($result['portrait']);
            $result['thumbnails'] = $this->build_thumbnails($result['portrait']);
            $now = time();
            $result['novice'] = 0;
            if (isset($result['create_timestamp']) && $now - intval($result['create_timestamp']) < $this->noviceTimes){
                $result['novice'] = 1;
            }
            unset($result['create_timestamp']);
            unset($result['portrait']);
            unset($result['province']);
            unset($result['city']);
            unset($result['phone']);
            unset($result['tags'], $result['other_tags']);
        }
        // 设置缓存
        if(empty($result)){
            return null;
        }
        return $result;
    }



    /**
     * 获取用户信息 电话号
     * @param $user_uid
     * @param default 默认 true:用户生成的UUID false:用户自增user_id
     * @return mixed
     */
    public function get_user_by_uid($user_uid,$default = true){

        // 关系数据库读取
        if($default) {
            $users = DB::table("user")
                ->where("uuid", '=', $user_uid)
                ->first($this->sql_user_fields);
        }else{
            $users = DB::table("user")
                ->where("user_id", "=", $user_uid)
                ->first($this->sql_user_fields);
        }

        $result = self::objToArray($users);

        if(!empty($result)){
            if(!empty($result['union_vest']) && $result['union_vest_switch'] ==1){
                $result['nickname'] = $result['union_vest'].'·'.$result['nickname'];
            }
            if(!empty($result['province']) && !empty($result['city'])){
                $result['home'] = $result['province'].'#'.$result['city'];
            }else{
                $result['home'] = '';
            }
            //图片尺寸适配
            $images_arr = json_decode($result['portrait'],true) ?? [];
            $result['adapt_images'] = empty($images_arr) ? [] :  build_adapt_images($images_arr ,$this->adapt_size);

            $result['images'] = $this->build_images($result['portrait']);
            $result['thumbnails'] = $this->build_thumbnails($result['portrait']);
            $now = time();
            $result['novice'] = 0;
            if (isset($result['create_timestamp']) && $now - intval($result['create_timestamp']) < $this->noviceTimes){
                $result['novice'] = 1;
            }
            unset($result['create_timestamp']);
            unset($result['portrait']);
            unset($result['province']);
            unset($result['city']);
            unset($result['phone']);
            unset($result['tags'], $result['other_tags']);
        }
        // 设置缓存
        if(empty($result)){
            return null;
        }
        return $result;
    }


    /**
     * 获取用户info
     * @param $user_id
     * @return mixed
     */
    public function get_user($user_id, $self = false){
        // 获取缓存
	    $user_item = $this->get_cache_user($user_id);
	    
        if ($user_item != null){
            if ($self == false){
                unset($user_item['phone']);
                unset($user_item['create_timestamp']);
            }
            $user_item['tags'] = isset($user_item['tags']) && $user_item['tags'] ? json_decode($user_item['tags'], true) : [];
            $user_item['other_tags'] = isset($user_item['other_tags']) && $user_item['other_tags'] ? json_decode($user_item['other_tags'], true) : [];

            //检查金V有效期
            if (!empty($user_item['v_start_time']) && time() < $user_item['v_start_time']) {
                $user_item['v'] = 0;
            }
            if (!empty($user_item['v_end_time']) && time() > $user_item['v_end_time']) {
                $user_item['v'] = 0;
            }

            return $user_item;
        }

        // 关系数据库读取
        $users = DB::table("user")
            ->where("user_id", "=", $user_id)
            ->first($this->sql_user_fields);
	$result = self::objToArray($users);

        if(!empty($result)){
            if(!empty($result['union_vest']) && $result['union_vest_switch'] ==1){
                $result['nickname'] = $result['union_vest'].'·'.$result['nickname'];
            }
            if(!empty($result['province']) && !empty($result['city'])){
                $result['home'] = $result['province'].'#'.$result['city'];
            }else{
                $result['home'] = '';
            }
            //图片尺寸适配
            $images_arr = json_decode($result['portrait'],true) ?? [];
            $result['adapt_images'] = empty($images_arr) ? [] :  build_adapt_images($images_arr ,$this->adapt_size);

            $result['images'] = $this->build_images($result['portrait']);
            $result['thumbnails'] = $this->build_thumbnails($result['portrait']);
            $now = time();
            $result['novice'] = 0;
            if (isset($result['create_timestamp']) && $now - intval($result['create_timestamp']) < $this->noviceTimes){
                $result['novice'] = 1;
            }
            //用户分类 2老用户 1新用户
            $result['user_cat'] = 2;
            if (isset($result['create_timestamp']) && $now - intval($result['create_timestamp']) < $this->oldUserTimes){
                $result['user_cat'] = 1;
            }
            $result['voice'] = $this->build_voice($result['voice']);
            // unset($result['create_timestamp']);
            unset($result['portrait']);
            unset($result['province']);
            unset($result['city']);

            //合并金V有效期
            $userSet = $this->getUserSet($user_id);
            $result['v_start_time'] = empty($userSet['v_start_time']) ? 0 : $userSet['v_start_time'];
            $result['v_end_time'] = empty($userSet['v_end_time']) ? 0 : $userSet['v_end_time'];
        }

        // 设置缓存
        if(!empty($result)){
            $search = new Search();
            // write_log("search", "indexUser-user-2", $result);
            $search->indexUser($result);
            $this->set_cache_user($result['user_id'], $result);
        }

        if ($self == false){
            unset($result['phone']);
            unset($result['create_timestamp']);
        }

        if (isset($result['phone']) && substr($result['phone'] , 0 , 1) == 2) {
            unset($result['phone']);
        }

        if ($result) {
            $result['tags'] = (isset($result['tags']) && $result['tags']) ? json_decode($result['tags'], true) : [];
            $result['other_tags'] = (isset($result['other_tags']) && $result['other_tags']) ? json_decode($user_item['other_tags'], true) : [];
        }

        //检查金V有效期
        if (!empty($result['v_start_time']) && time() < $result['v_start_time']) {
            $result['v'] = 0;
        }
        if (!empty($result['v_end_time']) && time() > $result['v_end_time']) {
            $result['v'] = 0;
        }

        return $result;
    }

    /**
     * 获得当前用户
     * @return mixed
     */
    public function get_current_user(){
	    $token = $this->get_cookies_token();
//        if ($token) {
//            write_log('get_cookies_token', 'token', $token);
//        }
        if (empty($token)){
            return null;
        }
        
        // 缓存读取
        $cur_user_id = $this->get_cache_token_userid($token);
        if ($cur_user_id == null){
            return null;
        }

        $is_forbid = $this->is_forbid($cur_user_id);
        if ($is_forbid){
            return null;
        }


        return $this->get_user($cur_user_id, true);

    }

    /**
     * @desc 获得当前用户id
     * @author zxiaofee
     * @date 2022-02-26
     * @return mixed
     */
    public function get_current_user_id(){
        $token = $this->get_cookies_token();
        if (empty($token)){
            return null;
        }
        // 缓存读取
        return $this->get_cache_token_userid($token);
    }

    /**
     * @desc 获得当前用户id
     * @author zxiaofee
     * @date 2022-02-26
     * @return mixed
     */
    public function get_current_user_cookie(){
        return $this->get_cookies_token();
    }

    /**
     * 获取当前设置的用户token
     * */
    public function getUserToken()
    {
        return $this->userToken;
    }

    /**
     * 刷新当前用的token 有效时长
     * @return bool
     */
    public function refresh_current_user(){
        $token = $this->get_cookies_token();
        $cur_user_id = $this->get_cache_token_userid($token);
        if ($cur_user_id == null){
            return false;
        }
        $expire = 3600*24*30;
        $this->set_cache_token_userid($token, $cur_user_id, $expire);
        $this->set_cookies_token($token, $expire);
        return true;
    }


    public function del_current_user(){
        $token = $this->get_cookies_token();
        $this->del_cache_token_userid($token);
        $this->del_cookies_token();
        return true;
    }


    /**
     * 设置当前用户
     * @param $user_id
     * @return bool
     * @throws \Exception
     */
    public function set_current_user($user_id){
        $user = $this->get_user($user_id, true);
        if ($user == null){
            return false;
        }
        $token = Uuid::uuid1();
        if (empty($token)){
            return false;
        }
        $expire = 3600*24*30;
        $this->set_cookies_token($token, $expire);
        $this->set_cache_token_userid($token, $user_id, $expire);

        //设置当前用户的token
        $this->userToken = $token;
        return true;
    }

    /**
     * 设置渠道商ID
     * @param int $user_id
     * @param string $channel_id
     * @return int
     */
    public function set_channel_id(int $user_id, string $channel_id){
        $ret = DB::table($this->table)->where(['user_id' => $user_id])
            ->update(['channel_id' => $channel_id]);
        $this->del_cache_user($user_id);
        return $ret;
    }


    /**
     * 设置cookies token
     * @param $token
     * @param $expire
     * @return true
     */
    private function set_cookies_token($token, $expire){
        setcookie($this->token_name, $token, time() + $expire, '/');
        header("set-token: $token");
        return true;
    }

    /**
     * 获取cookies token
     * @return null|string
     */
    private function get_cookies_token(){
        if (!empty($_SERVER['HTTP_REQUESTED_TOKEN'] ?? '')) {
            return $_SERVER['HTTP_REQUESTED_TOKEN'];
        }
        if (!empty($_SERVER['HTTP_TOKEN'] ?? '')) {
            return $_SERVER['HTTP_TOKEN'];
        }
        if (!empty($_SERVER['HTTP_AUTHORIZATION'] ?? '')) {
            return $_SERVER['HTTP_AUTHORIZATION'];
        }

        if (empty($_COOKIE[$this->token_name])){

            if (!empty($_SERVER['HTTP_REQUESTED_TOKEN'] ?? '')) {
                return $_SERVER['HTTP_REQUESTED_TOKEN'];
            }
            if (!empty($_SERVER['HTTP_TOKEN'] ?? '')) {
                return $_SERVER['HTTP_TOKEN'];
            }
            return null;
        }
        return $_COOKIE[$this->token_name];
    }

    public function getToken()
    {
        return $this -> get_cookies_token();
    }


    /**
     * 删除cookies token
     * @return bool
     */
    private function del_cookies_token(){
        setcookie($this->token_name, "" , time()-1,'/');
        return true;
    }


    /**
     * 设置token缓存
     * @param $token
     * @param $user_id
     * @param float|int $expire_time
     * @return bool
     */
    private function set_cache_token_userid($token, $user_id, $expire_time=3600){

        $old_token = Redis::HGET($this->redis_cache_user_token_hash, $user_id);
        if (!empty($old_token)){
            $this->del_cache_token_userid($old_token);
        }
        $key = $this->redis_cache_user_token_key . $token;
        Redis::SET($key, $user_id, 'EX', $expire_time);
        Redis::HSET($this->redis_cache_user_token_hash, $user_id, $token);
        return true;
    }

    /**
     * @param  $token
     * @return array|false|mixed
     * @desc 根据user_token 查询用户信息
     */
    public function getUserByToken($token)
    {
        $key = $this->redis_cache_user_token_key . $token;
        $userId = Redis::get($key) ?? 0;
        if (!$userId) {
            return false;
        }
        return $this->get_user($userId);

    }

    /**
     * 获取token缓存
     * @param $token
     * @return int|null
     */
    public function get_cache_token_userid($token){
        $key = $this->redis_cache_user_token_key . $token;
        $ret = Redis::GET($key);
        if ($ret == null){
            return null;
        }
        return intval($ret);
    }


    /**
     * 删除token缓存
     * @param $token
     * @return bool
     */
    private function del_cache_token_userid($token){
        $key = $this->redis_cache_user_token_key . $token;
        Redis::DEL($key);
        return true;
    }



    /**
     * 设置用户缓存
     * @param $user_id
     * @param $user_item
     * @param $expire_time
     * @return bool
     */
    private function set_cache_user($user_id, $user_item, $expire_time=3600){
        $key = $this->redis_cache_user_key . $user_id;
        Redis::SET($key, json_encode($user_item), 'EX', $expire_time);
        return true;
    }

    /**
     * 获取用户缓存
     * @param $user_id
     * @return array|null
     */
    private function get_cache_user($user_id){
        $key = $this->redis_cache_user_key . $user_id;
        $ret = Redis::GET($key);
        if ($ret == null){
            return null;
        }
        return json_decode($ret, true);
    }


    /**
     * 删除用户缓存
     * @param $user_id
     * @return bool
     */
    private function del_cache_user($user_id){
        $search = new Search();
        $search->delUser($user_id);
        $key = $this->redis_cache_user_key . $user_id;
        Redis::DEL($key);
        return true;
    }

    public function clear_cache($user_id){
        $r = $this->del_cache_user($user_id);
    }

    /**
     * 添加图片url列表
     * @param $portrait_json
     * @return array
     */
    public function build_images($portrait_json){
        $portrait = json_decode($portrait_json,true);
        $images = [];
        if($portrait){
            foreach($portrait as $k => $v){
                if (strtolower(substr($v, 0, 4)) == "http"){
                    $images[$k] = $v;
                }
                else{
                    $images[$k] = getPicDomain().$v;
                }

            }
        }
        return $images;
    }


    /**
     * 生成缩略图
     * @param $portrait_json
     * @return array
     */
    public function build_thumbnails($portrait_json){
        $portrait = json_decode($portrait_json,true);
        $images = [];
        if($portrait){
            foreach($portrait as $k => $v){
                if (strtolower(substr($v, 0, 4)) == "http"){
                    $images[$k] = $v;
                }
                else{
                    $arr = pathinfo($v);
                    $images[$k] = getPicDomain().$v . '?x-oss-process=style/thumbnails';
                    if (isset($arr['extension']) && strtolower($arr['extension']) == 'gif'){
                        $images[$k] = getPicDomain().$v;
                    }
                }

            }
        }
        return $images;
    }

    /**
     * @desc 用户反馈
     * @param integer $user_id
     * @param string $content
     * @return bool
     * */
    public function feedback_commit($user_id, $content, $images='')
    {
        $data = ['user_id'=>$user_id,'fe_content'=>$content,'fe_imgs'=>$images,'create_timestamp'=>time()];
        return DB::table($this->feedbackTable)->insert($data);
    }

    /**
     * 处理用户反馈
     * @param $update 更新数据
     * @param $id 反馈id
     */
    public function feedback_update($update,$id)
    {
        DB::beginTransaction();
        try{
            DB::table($this->feedbackTable)->where('id',$id)->update($update);
            DB::commit();
        }catch (\Exception $e)
        {
            DB::rollBack();
            return $e->getMessage();
        }
        return true;
    }
    
    /**
     * 生成用户UID
     * @return int
     */
    public function generated_uid(){
        $data = Redis::Lrange($this->redis_user_uid_generated_db,0,1000);
        $key = array_rand($data,1);
        Redis::LREM($this->redis_user_uid_generated_db,1,$data[$key]);
        return $data[$key];
        //return Redis::LPOP($this->redis_user_uid_generated_db);
    }


    /**
     * 搜索用户
     * @param $keyword
     * @return array
     */
    public function search($keyword){
        $keyword = filterEmoji($keyword);

        $search = new Search();
        return $search->searchUser($keyword, 0, 30);

        /*
        $result = DB::table($this->table)
            ->where('nickname', 'like', "%$keyword%")
            ->orWhere('uuid', 'like', "%$keyword%")
            ->limit(30) //最大返回30条搜索数据
            ->get($this->sql_user_fields);

        $result = self::objToArray($result);

        $ret_data = [];
        $now = time();
        for ($i = 0; $i < count($result); $i++){
            if ($result[$i]['user_id'] == 11 || $result[$i]['user_id'] == 12 || $result[$i]['user_id'] == 13 || $result[$i]['user_id'] == 14 || $result[$i]['user_id'] == 16){
                continue;
            }
            if(!empty($result[$i]['province']) && !empty($result[$i]['city'])){
                $result[$i]['home'] = $result[$i]['province'].'#'.$result[$i]['city'];
            }else{
                $result[$i]['home'] = '';
            }
            $result[$i]['images'] = $this->build_images($result[$i]['portrait']);
            $result[$i]['thumbnails'] = $this->build_thumbnails($result[$i]['portrait']);
            $result[$i]['novice'] = 0;
            if (isset($result[$i]['create_timestamp']) && $now - intval($result[$i]['create_timestamp']) < $this->noviceTimes){
                $result[$i]['novice'] = 1;
            }
            unset($result[$i]['create_timestamp']);
            unset($result[$i]['portrait']);
            unset($result[$i]['province']);
            unset($result[$i]['city']);
            unset($result[$i]['phone']);
            // 添加到返回列表
            $ret_data[] = $result[$i];
            // 设置用户缓存
            //$this->set_cache_user(intval($result[$i]['user_id']), $result[$i]);
        }
        return $ret_data;
        */
    }

    /**
     * 关键字搜索
     * */
    public function keywordsSearch($keywords,$page,$limit){
        $keywords = filterEmoji($keywords);

        $search = new Search();

        $result = $search->searchUser($keywords, $page, $limit);

        /*
        $notInUserIds = [11, 12, 13, 14, 16];

        $db = DB::table($this->table)
            ->where('nickname', 'like', "%$keywords%")
            ->whereNotIn('user_id', $notInUserIds )
            ->orWhere('uuid', 'like', "%$keywords%")
            ->whereNotIn('user_id', $notInUserIds);

        // 总条数
        $totalCount = $db->count('user_id');

        // 总数
        $result = $db->offset($page * $limit)
            ->limit($limit)
            ->get($this->sql_user_fields);
        $result = self::objToArray($result);

        $timeStamp = time();
        foreach ($result as $key => $value) {
            if(!empty($value['province']) && !empty($value['city'])){
                $result[$key]['home'] = $value['province'].'#'.$value['city'];
            }else{
                $result[$key]['home'] = '';
            }

            $result[$key]['images'] = $this->build_images($value['portrait']);
            $result[$key]['thumbnails'] = $this->build_thumbnails($value['portrait']);
            $result[$key]['novice'] = 0;
            if (isset($value['create_timestamp']) && ($timeStamp - intval($value['create_timestamp']) < $this->noviceTimes)){
                $result[$key]['novice'] = 1;
            }

            unset($result[$key]['create_timestamp']);
            unset($result[$key]['portrait']);
            unset($result[$key]['province']);
            unset($result[$key]['city']);
            unset($result[$key]['phone']);
        }
        */

        return $this->checkPageData($page, $limit, 0, $result);
    }

    public function activeZm(){
        $user = $this->get_current_user();
        $condition = ["user_id" => $user['user_id']];
        return $this->singleUpdate($condition,['active_certify',1]);
    }

    /**
     * 根据推荐码获取用户id
     * @param string $code  推荐码
     * @return mixed
     */
    public function get_user_id_by_code(string $code){
        $condition = ['recommend_code' => $code];
        return collect($this->getSingle($condition,['user_id']))->first();
    }

    /**
     * 根据推荐码获取用户id
     * @param string $code  推荐码
     * @return mixed
     */
    public function get_current_uid(){
        $token = $this->get_cookies_token();
        if (empty($token)){
            return null;
        }
        return $this->get_cache_token_userid($token);
    }

    /**
     * 更新guid
     * @param int $user_id
     * @param string $guid
     * @return int
     */
    public function set_guid(int $user_id,string $guid){
        $ret = DB::table($this->table)->where(['user_id' => $user_id])
            ->update(['guid' => $guid]);
        $this->del_cache_user($user_id);
        return $ret;
    }

    /**
     * 更新用户身份信息
     */
    public function updateUserIdentity($userId, $updata, $where=[]){
        $data = [];
        if(isset($updata['voice'])) {
            $data['voice'] = $updata['voice'];
        }
        if(isset($updata['voice_time'])) {
            $data['voice_time'] = $updata['voice_time'];
        }
        if(isset($updata['sign'])) {
            $data['sign'] = $updata['sign'];
        }
        if(isset($updata['identity_role'])) {
            $data['identity_role'] = $updata['identity_role'];
        }
        if(isset($updata['identity_status'])) {
            $data['identity_status'] = $updata['identity_status'];
        }
        if(empty($data)) {
            return false;
        }

        $query = DB::table($this->table)->where('user_id', $userId);
        if(!empty($where['identity_status'])) {
            $query = $query->where('identity_status', $where['identity_status']);
        }

        $ret = $query->update($updata);
        $this->del_cache_user($userId);
        return $ret;
    }

    /**
     * 更新用户信息
     */
    public function updateUserByData($userId, $updata){
        $data = [];
        if(isset($updata['gender'])) {
            $data['gender'] = $updata['gender'];
        }
        if(empty($data)) {
            return false;
        }

        $ret = DB::table($this->table)->where('user_id', $userId)
            ->update($updata);
        $this->del_cache_user($userId);
        return $ret;
    }


    /**
     * 判断用户是否被封
     * @param $user_id
     * @return bool
     */
    public function is_forbid($user_id){
        $user = $this->get_user($user_id);
        if (!empty($user['guid'])){
            if (Redis::HEXISTS($this->redis_device_forbid_key, $user['guid'])){
                return 2;
            }
        }
        $timeout = Redis::HGET($this->redis_user_forbid_key, $user_id);
        if ($timeout === null){
            return false;
        }
        if ($timeout == 0){
            return 2;
        }
        if (time() <= $timeout){
            return 1;
        }

        return false;
    }
    
    /**
     * 获取登录用户设备是否被禁用
     */
    public function device_frobid($user_id)
    {
        $user = $this->get_user($user_id);
        $status = 2;
        if(!empty($status)){
            $status = $this->get_forbid_device($user['guid']);
        }
        return $status;
    }
    /**
     * 封禁设备
     * @param $guid  手机唯一标识
     */
    public function set_forbid_device($guid)
    {
        Redis::hset($this->redis_device_forbid_key, $guid, time());
    }

    /**解封设备
     * @param $guid
     */
    public function del_forbid_device($guid)
    {
        Redis::hdel($this->redis_device_forbid_key, $guid);
    }

    public function get_forbid_device($guid)
    {
        if (Redis::HEXISTS($this->redis_device_forbid_key, $guid)){
            return 1;
        } else {
            return 2;
        }
    }

    public function resetDevice($userId){
        DB::table("user")
        ->where("user_id", "=", $userId)
        ->update(['guid' => $userId]);
        $redisKey = $this->redis_cache_user_key.$userId;
        Redis::EXPIRE($redisKey, 1);
        return true;
    }

    /**
     * 屏蔽用户
     * @param int $user_id
     */
    public function set_forbid_user(int $user_id, int $timeout){
        if (empty($timeout)){
            $timeout = 0;
        }

        if(!isset($uuid)){
            $users = DB::table("user")
                ->where("user_id", "=", $user_id)
                ->first();
            $result = self::objToArray($users);
            $create = [
                'user_id' => $user_id ?? "",
                'uuid' => $result['uuid'] ?? "",
                'operate_info' => "登录设备超出限制",
                'operate_time' => time(),
                'forbid_type' => 1,
                'operate_type' => 1,
                'block_time' => 0,
                'reason_id' => 40
            ];
            DB::table("user_block_log")->insert($create);


        }

        Redis::HSET($this->redis_user_forbid_key,$user_id, $timeout);
    }

    /**
     * 解封用户
     * @param int $user_id
     */
    public function remove_forbid_user(int $user_id){
//         DB::table("user_block_log")
//            ->where(['user_id' => $user_id])
//            ->delete();
        DB::table("user_login_log")
            ->where(['user_id' => $user_id])
            ->delete();
        Redis::HDEL($this->redis_user_forbid_key,$user_id);
    }


    /**
     * 屏蔽列表
     * @return array|false
     */
    public function get_forbid_list(){
        $forbid = Redis::HGETALL($this->redis_user_forbid_key);
        return $forbid;
    }


    /**
     * 是否管理员
     * @param $user_id
     * @return bool
     */
    public function is_super($user_id){
        $user = $this->get_user($user_id);
        if (isset($user['super']) && $user['super'] == 1){
            return true;
        }
        return false;
    }

    public function set_certify($user_id, int $state=1){
        DB::table("user")
            ->where("user_id", "=", $user_id)
            ->update(['active_certify' => $state]);
        return $this->del_cache_user($user_id);
    }

    /**
     * 设置UUID
     * @param $userId
     * @param $uid
     */
    public function setUid($userId, $uid){
        DB::table("user")
            ->where("user_id", "=", $userId)
            ->update(['uuid' => $uid]);
        $this->del_cache_user($userId);
    }


    /**
     * 设置靓号
     * @param $userId
     * @param $liang 0.非靓号、1.靓号
     * @param $newUuid  靓号号码
     */
    public function setLiang($userId, $liang){
        $res = DB::table("user")
            ->where("user_id", "=", $userId)
            ->update(['liang' => $liang]);
        $this->del_cache_user($userId);
        return $res;
    }


    /**
     * 设置超级管理
     * @param $userId
     * @param $super 0.非超管、1.超管
     */
    public function setSuper($userId, $super){
        DB::table("user")
            ->where("user_id", "=", $userId)
            ->update(['super' => $super]);
        $this->del_cache_user($userId);
    }


    /**
     * 设置官方
     * @param $userId
     * @param $official 0.非官方、1.官方
     */
    public function setOfficial($userId, $official){
        DB::table("user")
            ->where("user_id", "=", $userId)
            ->update(['official' => $official]);
        $this->del_cache_user($userId);
    }


    /**
     * 设置接待(巡房)
     * @param $userId
     * @param $waiter 0.非接待、1.接待
     */
    public function setWaiter($userId, $waiter){
        DB::table("user")
            ->where("user_id", "=", $userId)
            ->update(['waiter' => $waiter]);
        $this->del_cache_user($userId);
    }


    /**
     * 设置加V
     * @param $userId int
     * @param $v int 0.取消加V、1.设置加V
     * @param $vDesc string 加V描述
     */
    public function setV($userId, $v, $vDesc){
        DB::table("user")
            ->where("user_id", "=", $userId)
            ->update(['v' => $v, 'v_desc' => $vDesc]);
        $this->del_cache_user($userId);
    }


    /**
     * 添加在线用户
     * @param $userId
     * @param $ts
     */
    public function addOnlineUser($userId, $ts){
        Redis::HSET($this->userOnlineMap, $userId, $ts);
        $user = $this->get_user($userId);
        if ($user['gender'] == 2){
            Redis::HSET($this->userOnlineWomanMap, $userId, $ts);
        }else{
            Redis::HSET($this->userOnlineManMap, $userId, $ts);
        }

        //在线用户列表，计算用户分数
        $userInfo = (new MeetingServices())->getMeetUserInfo($userId, $userId);
        (new Meet())->setOnlineUserLevelCache($userInfo['level'], $userId);
    }

    /**
     * 判断用户是否在线
     *
     * @param int $userId
     * @return bool
     */
    public function checkUserOnlineStatus(int $userId): bool
    {
        if (Redis::HEXISTS($this->userOnlineMap, $userId)) {
            return true;
        }

        return false;
    }

    /**
     * 获取在线用户
     * @return array
     */
    public function getOnlineUserArr(){
        $userIdArr = Redis::HKEYS($this->userOnlineMap);
        if (empty($userIdArr)){
            return [];
        }
        return $userIdArr;
    }

    /**
     * 获取在线用户 女
     * @return array
     */
    public function getOnlineWomanArr(){
        $userIdArr = Redis::HKEYS($this->userOnlineWomanMap);
        if (empty($userIdArr)){
            return [];
        }
        return $userIdArr;
    }

    /**
     * 获取在线用户 男
     * @return array
     */
    public function getOnlineManArr(){
        $userIdArr = Redis::HKEYS($this->userOnlineManMap);
        if (empty($userIdArr)){
            return [];
        }
        return $userIdArr;
    }

    /**
     * 删除在线用户
     * @param $userId
     */
    public function delOnlineUser($userId){
        Redis::HDEL($this->userOnlineMap, $userId);
        Redis::HDEL($this->userOnlineManMap, $userId);
        Redis::HDEL($this->userOnlineWomanMap, $userId);
    }

    /**
     * 设置账号是否异常
     * @param $userId
     * @param $is_abnormal  0 -正常 1 - 异常
     */
    public function setAbnormal($userId, $is_abnormal){
        DB::table("user")
            ->where("user_id", "=", $userId)
            ->update(['is_abnormal' => $is_abnormal]);
        $this->del_cache_user($userId);
    }

    /**
     * 添加声音资料地址
     * @param $voice
     * @return string
     */
    public function build_voice($voice){
        return $voice ? getPicDomain().$voice : "";
    }

    /**
     * 设置账号是否异常
     * @param $userId
     * @param $cpStatus  0 - 显示 1 - 隐藏
     * @return boolean
     */
    public function setCpStatus($userId, $cpStatus){
        $ret = DB::table("user")
            ->where("user_id", "=", $userId)
            ->update(['cp_status' => $cpStatus]);
        $this->del_cache_user($userId);
        return $ret;
    }

    /**
     * 获取账号被封时间
     * @param $userId
     * @return boolean
     */
    public function getForbidTime($userId){
        return $timeout = Redis::HGET($this->redis_user_forbid_key, $userId);
    }

    /**
     * 获取账号最后device_token
     * @param $userId
     * @return boolean
     */
    public function getUserDeviceTokenByUid($userId){
        return $timeout = Redis::HGET($this->redis_user_device_token_key, $userId);
    }

    /**
     * 设置账号最后device_token
     * @param $userId
     * @param $deviceToken
     * @return boolean
     */
    public function setUserDeviceToken($userId, $deviceToken){
        return $timeout = Redis::HSET($this->redis_user_device_token_key, $userId, $deviceToken);
    }

    /**
     * 获取用户短信验证码缓存
     * @param $phone
     * @param $deviceToken
     * @return boolean
     */
    public function getUserSmsCache($phone){
        return (int)Redis::GET($this->smsPrefix . $phone);
    }

    /**
     * 查询是否申请注销
     * @param $userId
     * @return boolean
     */
    public function getAccountCancel($userId){
        return (int)Redis::HGET($this->userAccountCancel, $userId);
    }

    /**
     * 账号注销
     * @param $userId
     * @param $data 账号注销数据
     * @return boolean
     */
    public function setAccountCancel($userId, $data = []){
        Redis::HSET($this->userAccountCancel, $userId, time());
        return Redis::HSET($this->userAccountCancelData, $userId, json_encode($data));
    }

    /**
     * 撤销账号注销
     * @param $userId
     * @return boolean
     */
    public function removeAccountCancel($userId){
        Redis::HDEL($this->userAccountCancel, $userId);
        Redis::HDEL($this->userAccountCancelData, $userId);
    }


    /**
     * 获取所有注销用户信息
     */
    public function getAllAccountCancel(){
        $data = Redis::HGETALL($this->userAccountCancelData);
        $ret = [];
        foreach ($data as $k => $v){
            $v = json_decode($v, true);
            $v['user_id'] = $k;
            $ret[] = $v;
        }
        return $ret;
    }


    /**
     * 添加注销记录到数据库
     * @param $userId
     * @param $phone
     */
    public function addUserAccountCancel($userId, $phone, $address, $regType, $regPhoneType, $msg){
        $data = [
            'user_id' => $userId,
            'phone' => $phone,
            'address' => $address,
            'reg_type' => $regType,
            'reg_phone_type' => $regPhoneType,
            'msg' => $msg
        ];
        $search = new Search();
        $search->delUser($userId);
        return DB::table('user_account_cancel')
            ->insert($data);
    }

    /**
     * 获取用户设置信息
     * @param $userId
     * @return array
     */
    public function getUserSet($userId){
        $key = $this->redis_user_set_key . $userId;
        $list = Redis::get($key);
        if(empty($list)){
            $list = DB::table($this->userSetTable)->where(['user_id' => $userId])->first();
            $list = self::objToArray($list);
            if(!empty($list)) {
                Redis::setex($key, 3600, json_encode($list));
            }
        }else{
            $list = json_decode($list, true);
        }
        $list['user_set_id'] = empty($list['user_set_id']) ? 0 : $list['user_set_id'];
        $list['user_id'] = $userId;
        $list['gift_notice'] = empty($list['gift_notice']) ? 1 : $list['gift_notice'];
        $list['no_msg_friend'] = empty($list['no_msg_friend']) ? 2 : $list['no_msg_friend'];

        return $list;
    }

    /**
     * 更新用户设置信息
     * @param $userId
     * @param $params 更新或新增数据
     * @return boolean
     */
    public function editUserSet($userId, $params = []){
        $ret = DB::table($this->userSetTable)->updateOrInsert(['user_id' => $userId], $params);
        if ($ret) {
            Redis::DEL($this->redis_user_set_key . $userId);
        }
        return $ret;
    }

    /**
     * 获取用户注册天数
     * @param $userId
     * @return integer
     */
    public function getUserRegisterDay($userId)
    {
        // 关系数据库读取
        $users = DB::table("user")
            ->where("user_id", "=", $userId)
            ->first($this->sql_user_fields);
        $result = self::objToArray($users);
        if (!$result) return 1;

        $startTime = ($result['create_timestamp']);
        $endTime = time();
        $timeDiff = $endTime-$startTime;
        return intval($timeDiff/86400);
    }

    /**
     * 获取用户年度报告缓存
     * @param $userId
     * @return array
     */
    public function getUserYearReportCache($userId)
    {
        $cache = Redis::HGET($this->userYearReportCacheKey, $userId);
        if ($cache) {
            return json_decode($cache, true);
        }
        return [];
    }

    /**
     * 保存用户年度报告缓存
     * @param $userId
     * @param $data
     * @return boolean
     */
    public function setUserYearReportCache($userId, $data)
    {
        return Redis::HSET($this->userYearReportCacheKey, $userId, json_encode($data));
    }


     /* 获取用户封号信息
     * @param $userId
     * @return Model|\Illuminate\Database\Query\Builder|mixed|null|object
     */
    public function getBlockInfo($userId){
        $result = DB::table('user_block_log')
            ->where('user_id', '=', $userId)
            ->orderByDesc('operate_time')
            ->first(['user_id', 'operate_type', 'operate_time', 'block_time','operate_info']);
        if (empty($result)){
            return null;
        }
        $result = $this->objToArray($result);
        if ($result['block_time'] == 0){
            $result['block_duration_time'] = 0;
        }else{
            $result['block_duration_time'] = $result['block_time'] - $result['operate_time'];
        }
        if ($result['operate_type'] == 0){
            return null;
        }
        if ($result['block_time'] == 0){
            return $result;
        }
        if ($result['block_time'] < time()){
            return null;
        }
        return $result;
    }

    /**
     * 获取虚假手机号
     * @return string
     */
    public function getFalseMobile()
    {
        $falseMobile = Redis::GET($this->userFalseMobile);
        if ($falseMobile) {
            $falseMobile = Redis::INCR($this->userFalseMobile);
        } else {
            $falseMobile = 20000000000;
            Redis::SET($this->userFalseMobile, $falseMobile);
        }
        return $falseMobile;
    }

    /**
     * 获取用户邀请列表
     * @param $userId
     * @return integer
     */
    public function getUserInviteList($userId)
    {
        // 关系数据库读取
        $users = DB::table("user")
            ->where("invite_uid", "=", $userId)
            ->orderBy("user_id", "desc")
            ->get($this->sql_user_fields);

        $result = self::objToArray($users);

        foreach ($result as $key => $value) {
            //图片尺寸适配
            $images_arr = json_decode($value['portrait'],true) ?? [];
            $result[$key]['adapt_images'] = empty($images_arr) ? [] :  build_adapt_images($images_arr ,$this->adapt_size);

            $result[$key]['images'] = @$this->build_images($value['portrait']);
            $result[$key]['thumbnails'] = @$this->build_thumbnails($value['portrait']);
            unset($result[$key]['tags'], $result[$key]['other_tags']);
        }

        return $result;
    }

    /**根据手机号生成token
     * @param $phone
     * @return string
     */
    public function generatedSmTokenId($phone){
        return md5('kk_'.$phone);
    }

    public function insertDeviceRisk($data){
        $insert_id = DB::table($this->deviceRiskTable)->insertGetId($data);
        return empty($insert_id) ? 0 : $insert_id;
    }

    public function getDeviceRisk($phone ,$device_id){
        $res = DB::table($this->deviceRiskTable)->where(['phone'=>$phone ,'device_id'=>$device_id])->first();
        return isset($res->id) ? $res : [];
    }

    public function userForbid($requestData)
    {
        $requestData['operate_time'] = time();
        return DB::table('user_block_log')->insertGetId($requestData);
    }


    /**
     * 根据guid设备号获取用户组
     *
     * @param string $guid 设备号
     * @return array
     * */
    public function getUserByGuid($guid)
    {
        $result = DB::table('user')->where(['guid' => $guid])->get(['user_id', 'guid', 'uuid as user_uid']);
        return $this->objToArray($result);

    }


    /**速配设置用户一分钟内匹配到的房间
     * @param $user_id
     * @param $room_id
     */
     public function set_user_remain_room($user_id ,$room_id){
        Redis::setex($this->redis_user_remain_room.$user_id.':'.$room_id ,$this->user_remain_room_time ,time());
     }

    /**速配获取这个房间用户1分钟内是否停留过
     * @param $user_id
     * @param $room_id
     * @return int
     */
     public function get_user_is_remain_room($user_id,$room_id){
        $time = Redis::get($this->redis_user_remain_room.$user_id.':'.$room_id);
        return empty($time) ? 0 : 1;
     }

    public function getCallPool(){
        $userIdArr = Redis::get($this->userCallPool);
        if (empty($userIdArr)){
            return [];
        }
        return explode(',', $userIdArr);
    }

    /**获取礼物墙数量开关
     * @param $user_id
     * @return int
     */
    public function getGiftSwitch($user_id){
         $status =  Redis::Hget($this->redis_user_gift_switch,$user_id) ?? 0;
         return $status;
    }

    /**设置礼物墙数量开关
     * @param $user_id
     * @param $status
     * @return mixed
     */
    public function setGiftSwitch($user_id, $status){
        Redis::HSET($this->redis_user_gift_switch ,$user_id ,$status);
        return $status;
    }

    //redis存储设备风险
    public function redisCacheDevice($key,$value,$expire_time = 300){
        Redis::setex($key,$expire_time,$value);
        return true;
    }
    //redis获取设备风险
    public function redisCacheDeviceGet($key){
        return Redis::get($key);
    }

    /**批量修改用户的公会马甲信息
     * @param $user_ids
     * @param $union_vest
     */
    public function batchSetUnionVest($user_ids,$union_vest,$switch){
        foreach ($user_ids as $user_id){
            DB::table($this->table)->where('user_id' ,$user_id)->update(array('union_vest'=>$union_vest,'union_vest_switch'=>$switch));
            $this->del_cache_user($user_id);
        }
    }

    /**
     * 管理后台审批后，批量修改用户的公会马甲信息
     * @param $user_ids
     * @param $union_vest
     */
    public function batchSetUnionVestNew($user_ids,$union_vest){
        foreach ($user_ids as $user_id){
            DB::table($this->table)->where('user_id' ,$user_id)->update(array('union_vest'=>$union_vest));
            $this->del_cache_user($user_id);
        }
    }

    /**从数据库中获取用户信息
     * @param $user_id
     * @return mixed
     */
    public function get_user_from_db($user_id){
        $res = DB::table($this->table)->where('user_id',$user_id)->first(['user_id','nickname','union_vest','union_vest_switch']);
        return $this->objToArray($res);
    }

    /**操作每日充值金额限制
     * @param $type
     * @param $id
     * @param array $data
     * @return int
     */
    public function curdRechargeLimit($type ,$id ,$data = []){
        switch ($type){
            case 'insert':
                $res = DB::table($this->rechargeLimitTable)->insertGetId($data);
                break;
            case 'update':
                $data['change_time'] = time();
                $res = DB::table($this->rechargeLimitTable)->where(['id' => $id])->update($data);
                break;
            case 'del':
                $res =  DB::table($this->rechargeLimitTable)->delete($id);
                break;
            default :
                $res = 0;
                break;
        }
        return $res;
    }

    /**获取用户每日充值限制
     * @param $user_id
     * @return mixed
     */
    public function getUserRechargeLimit($user_id){
        $res = DB::table($this->rechargeLimitTable)
            ->where('user_id',$user_id)
            ->where('status',1)
            ->first();
        return $this->objToArray($res);
    }

    /**获取默认头像
     * @return array|mixed
     */
    public function getDefaultPortrait(){
        $res = DB::table($this->defaultPortraitTable)->where('type',0)->get();
        return empty($res) ? []  : $this->objToArray($res);
    }

    /**
     * 获取用户邀请列表+房主同实名认证用户
     * @param $userId
     * @return array
     */
    public function getCurMonthUserInviteList($userId)
    {
//        $startDay = date('Y-m-01 00:00:00', strtotime("-1 month"));
//        $endDay = date('Y-m-d 23:59:59', strtotime("$startDay +1 month -1 day"));
////         关系数据库读取
//        $users = DB::table("user")
//            ->where("invite_uid", "=", $userId)
//            ->where('create_timestamp','>=',1604160000)
//            ->orderBy("user_id", "desc")
//            ->get($this->sql_user_fields);
//
//        $result = self::objToArray($users);
//        return $result;

        $user_verify = DB::table('user_verify')->select('idcard_number')->where('user_id' ,$userId)->first();
        if(!empty($user_verify)){
            $users_ = DB::table('user_verify')->select('user_id')->where('idcard_number' ,$user_verify->idcard_number)->get();
            $users_ = $this->objToArray($users_);
        }
        $user_ids = !empty($users_) ? implode(',',array_column($users_ ,'user_id'))  : 0;
        $sql = "select user_id from zb_user where (create_timestamp >= 1722441600 and invite_uid = {$userId}) or user_id in ({$user_ids})" ;
        $users = DB::select($sql);
        return self::objToArray($users);
    }

    /**获取测试用户id
     * @return array
     */
    public function get_test_users(){
//        $test_users = Redis::HGETALL($this->redis_test_user_ids);
//        return empty($test_users) ? [] : array_keys($test_users);

        $systemModel = new System();
        $configMap = $systemModel->get_config();
        if (empty($configMap['white_game_user']['value'])) {
            return [];
        }

        return explode(",", $configMap['white_game_user']['value']);
    }

    /**根据手机号获取风险信息
     * @param $phone
     * @return bool
     */
    public function getDeviceRiskByPhone($phone){
        $res = DB::table($this->deviceRiskTable)->select('id')->where('phone' , $phone)->first();
        return isset($res->id);
    }

    /**根据手机号或者设备获取风险信息
     * @param $phone
     * @return bool
     */
    public function getDeviceRiskByPhoneOrGuid($phone, $guid){
        $res = DB::table($this->deviceRiskTable)->select('id')->whereRaw("(`phone`='$phone' or `guid`='$guid') and `risk_level`='REJECT'")->first();
        return isset($res->id);
    }

    /**设置指定原因封号的ip前三位
     * @param $user_id
     * @param $ip
     */
    public function set_forbid_ip($user_id ,$ip){
        $arrStr = explode('.',$ip);
        $ip_three = $arrStr[0].'.'.$arrStr[1].'.'.$arrStr[2];
        Redis::setex($this->redis_forbid_ip.$ip_three ,2*24*60*60 ,$user_id);
    }

    /**判断ip是否在封禁的ip里
     * @param $ip
     * @return int
     */
    public function get_forbid_ip($ip){
        $arrStr = explode('.',$ip);
        $ip_three = $arrStr[0].'.'.$arrStr[1].'.'.$arrStr[2];
        return Redis::get($this->redis_forbid_ip .$ip_three) ?? 0;
    }

    /**设置/取消/修改 备注
     * @param $type
     * @param $params
     * @return int
     */
    public function curdUserRemark($type ,$params){
        $ret = 0;
        switch ($type){
            case 1:
                $ret = DB::INSERT("INSERT INTO zb_{$this->userRemarkTable} (`user_id`,`remark_user_id`,`remark_name`) VALUE({$params['user_id']},{$params['remark_user_id']},'{$params['remark_name']}') ON DUPLICATE KEY UPDATE remark_name='{$params['remark_name']}'");
                break;
            case 2:
                $ret = DB::table($this->userRemarkTable)
                    ->where(['user_id'=>$params['user_id'] ,'remark_user_id'=>$params['remark_user_id']])
                    ->delete();
                break;
        }
        if($type !=2){
            Redis::HSET($this->redis_user_remark . $params['user_id'], $params['remark_user_id'] ,$params['remark_name']);
        }else{
            Redis::HDEL($this->redis_user_remark . $params['user_id'], $params['remark_user_id']);
        }
        if(Redis::TTL($this->redis_user_remark . $params['user_id']) == -1){
            $res = DB::table($this->userRemarkTable)->where('user_id' , $params['user_id'])->get();
            $res = $this->objToArray($res);
            $data = array();
            foreach ($res as $r){
                $data[$r['remark_user_id']] = $r['remark_name'];
            }
            Redis::HMSET($this->redis_user_remark . $params['user_id'] ,$data);
            Redis::EXPIRE($this->redis_user_remark . $params['user_id'],24 * 60 * 60);
        }
        return $ret;
    }

    /**获取用户备注
     * @param $user_id
     * @param int $remark_user_id
     * @return mixed
     */
    public function getUserRemark($user_id ,$remark_user_id = 0){
        if(!empty($remark_user_id)){
            return Redis::HGET($this->redis_user_remark.$user_id ,$remark_user_id) ?? '';
        }else {
            return Redis::HGETALL($this->redis_user_remark.$user_id) ?? [];
        }
    }


    /**
     * @param $userId
     * @param $diamondNum
     * @return bool
     * @desc 获取未实名的用户是否可以充值
     */
    public function getNoRealIsAllowRecharge($userId, $diamondNum)
    {
        //获取用户之前总充值数
        $total = Redis::get(self::NO_REAL_NAME_RECHARGE_TOTAL_NUM . $userId) ?? 0;
        if ($total + $diamondNum > self::NO_REAL_NAME_RECHARGE_MAX_LIMIT) {
            return false;
        }
        //当日充值
        $day = Redis::get(self::NO_REAL_NAME_RECHARGE_DAY_NUM . $userId . ':' . date('Ymd')) ?? 0;
        if ($day + $diamondNum > self::NO_REAL_NAME_RECHARGE_DAY_LIMIT) {
            return false;
        }
        return true;
    }

    /**
     * 获取用户标签
     */
    public function userTags() {
        $res = DB::table($this->userTagsTable)
        ->where('status', 0)
        ->orderBy('sort', 'DESC')
        ->get(['tag_id', 'name', 'type']);
        return $this->objToArray($res);
    }

    /**
     * 获取用户标签
     */
    public function userTagsWithCat() {
        $tags = DB::table($this->userTagsTable)
            ->where('status', 0)
            ->where('type', 0)
            ->orderBy('sort', 'DESC')
            ->get(['tag_id', 'cat', 'name', 'type', 'sort']);
        $tags = $this->objToArray($tags);

        $cats = DB::table($this->userTagsCatTable)
            ->where('status', 0)
            ->where('type', 0)
            ->orderBy('sort', 'DESC')
            ->get(['id', 'name', 'sort', 'type']);
        $cats = $this->objToArray($cats);
        $catMap = [];
        foreach ($cats as $cat) {
            $catMap[$cat['id']] = $cat;
            $catMap[$cat['id']]['tags'] = [];
        }
        foreach ($tags as $tag) {
            if (isset($catMap[$tag['cat']])) {
                $catMap[$tag['cat']]['tags'][] = $tag;
            }
        }

        return array_values($catMap);
    }

    /**
     * 设置用户标签
     */
    public function setUserTags(int $userId, array $tags = [], string $field = 'tags') {
        $tags = json_encode($tags);
        DB::table($this->table)->where('user_id', $userId)->update([$field => $tags]);
        $this->del_cache_user($userId);
        return true;
    }

    /**
     * 创建用户个性标签
     */
    public function createUserTag(array $data = []): int {
        return DB::table($this->userTagsTable)->insertGetId($data);
    }

    /**
     * 编辑用户个性标签
     */
    public function updateUserTag(int $id, array $data = []): int {
        return DB::table($this->userTagsTable)->where('tag_id', $id)->update($data);
    }



    /**
     * 创建用户个性标签分类
     */
    public function createUserTagsCat(array $data = []): int
    {
        return DB::table($this->userTagsCatTable)->insertGetId($data);
    }

    /**
     * 编辑用户个性标签分类
     */
    public function updateUserTagsCat(int $id, array $data = []): int
    {
        return DB::table($this->userTagsCatTable)->where('id', $id)->update($data);
    }
    /**
     * 删除用户个性标签分类
     */
    public function delUserTagsCat(int $id, array $data = []): int
    {
        return DB::table($this->userTagsCatTable)->where('id', $id)->delete();;
    }




    public function getUserInfoByCondition(array $condition = [], array $fields = ['*']): array {
        $res = DB::table($this->table)->where($condition)->first($fields);
        if(!$res) return [];
        return self::objToArray($res);
    }
    public function get_user_guid($user_id){
        $res = DB::table($this->table)->where('user_id',$user_id)->first(['guid']);
        if(!$res) return [];
        return self::objToArray($res);
    }

    /**
     * 添加测试用户id
     * @return array
     */
    public function addTestUser($user_id){
        return Redis::HSET($this->redis_test_user_ids,$user_id,'');
    }

    /**
     * 删除测试用户id
     * @return array
     */
    public function delTestUser($user_id){
        return Redis::HDEL($this->redis_test_user_ids,$user_id);
    }

    public function getUserInfoByIds($userIds)
    {
        $list = DB::table($this->getTable())->whereIn('user_id', $userIds)->get(['user_id','uuid','nickname','gender','birthday','portrait','mood_id', 'identity_role', 'identity_status'])->toArray();
        $list = $this->objToArray($list);

        return $list;
    }

    /**
     * 根据uuids获取用户信息
     *
     * @param array $uuids
     * @return array
     */
    public function getUserInfoByUuids($uuids)
    {
        $result = DB::table($this->getTable())->whereIn('uuid', $uuids)->get(['user_id','uuid','nickname'])->toArray();

        return $this->objToArray($result);
    }

    public function getTenMinRegistUsers(){
        $timestart = time() - 600;
        $users = DB::table($this->table)
            ->select(['user_id','uuid', 'nickname', 'create_time'])
            ->where('create_timestamp','>' ,$timestart)
            ->get();
        $users = $this->objToArray($users);
        return $users;
    }

    public function getWithinOnDayRegistUsersByUids($uids){
        $timestart = time() - 3600 * 24;
        $users = DB::table($this->table)
            ->select(['user_id','uuid', 'nickname', 'create_time'])
            ->where('create_timestamp','>' ,$timestart)
            ->whereIn('user_id', $uids)
            ->get();
        $users = $this->objToArray($users);
        return $users;
    }


    public function getUserByUuid($uuid){
        $result = DB::table($this->getTable())->where('uuid', $uuid)->first();
        return $this->objToArray($result);
    }


    public static function isLockedByLoginPasswordErr($phone) : bool {
        $key = 'USER:LOGIN:PASSWORD_ERR:NUM:' . $phone;
        $failed = Redis::Get($key)??0;
        if ($failed >= 6) {
            return true;
        }
        return false;
    }

    public static function addLoginPasswordErrNum($phone) : int {
        $key = 'USER:LOGIN:PASSWORD_ERR:NUM:' . $phone;
        $res = Redis::incr($key);
        if(Redis::TTL($key) == -1){
            Redis::EXPIRE($key, 10 * 60);
        }
        return $res;
    }

    public function getUserWealthBalance($userId){
        $wealthBalance = DB::table('finance_wallet')->where('user_id',$userId)->select(['wealth_balance'])->first();
        return $wealthBalance && isset($wealthBalance->wealth_balance)?$wealthBalance->wealth_balance:0;
    }

    /**
     * 检查用户禁麦状态
     * @param $userId
     * @return bool true禁麦;false正常
     **/
    public function getMicroBlockStatus($userId)
    {
        $key = sprintf($this->redis_micro_block, $userId);
        $cache = Redis::get($key);

        if ($cache !== null) {
            $result = json_decode($cache, 1);
        } else {
            $result = DB::table($this->userMicroBlockLogTable)
                ->where('user_id', '=', $userId)
                ->orderByDesc('id')
                ->first(['operate_type', 'operate_time', 'block_time']);

            $result = !empty($result) ? $this->objToArray($result) : [];
            
            //写redis缓存
            Redis::setex($key, 5 * 60, json_encode($result));
        }

        //没有禁麦
        if (empty($result)) {
            return false;
        }
        //解禁状态
        if (empty($result['operate_type'])) {
            return false;
        }
        //已过期
        if (time() > $result['operate_time'] + $result['block_time'] * 60) {
            return false;
        }
        return true;
    }

    /**
     * 检查用户禁麦次数
     * @param $userId
     * @return int
     **/
    public function countMicroBlock($userId)
    {
        $result = DB::table($this->userMicroBlockLogTable)
            ->where('user_id', '=', $userId)
            ->where('operate_type', '=', 1)
            ->count();
        return $result;
    }

    /**
     * 用户禁麦
     * @param $userId
     * @return bool
     **/
    public function userMicroBlock($userId, $operateInfo, $operateType, $blockTime = 0)
    {
        $data = [
            'user_id' => $userId,
            'block_time' => $blockTime,
            'operate_type' => $operateType,
            'operate_info' => $operateInfo,
            'operate_time' => time()
        ];

        $result = DB::table($this->userMicroBlockLogTable)->insert($data);

        if ($result) {
            //写redis缓存
            $key = sprintf($this->redis_micro_block, $userId);
            if ($operateType == 1) {
                Redis::setex($key, 5 * 60, json_encode($data));
            } else {
                Redis::setex($key, 5 * 60, json_encode([]));
            }
        }

        return $result;
    }

    /**
     * 设置用户头像
     * @param $user_id int
     * @param $images string|array
     * @return int
     */
    public function set_portrait($user_id, $images){

        if(is_array($images)){
            $images = json_encode($images);
        }

        $result = DB::table("user")
            ->where("user_id", "=", $user_id)
            ->update(['portrait' => $images]);

        $this->del_cache_user($user_id);

        return $result;
    }

    /**
     * 手机号检查是否在不可被邀请中
     */
    public function checkInNoInvite($mobile_phone){
        if(empty($mobile_phone)) {
            return false;
        }

        $result = DB::table($this->user_noinvite_table)
            ->where("mobile_phone", "=", $mobile_phone)
            ->first();
        $result = self::objToArray($result);
        if(empty($result)) {
            return false;
        }else{
            return true;
        }
    }

    /**
     * 记录用户活跃
     * @return mixed
     */
    public function saveUserActive(){
        $token = $this->get_cookies_token();
        if (empty($token)){
            return null;
        }
        // 缓存读取
        $userId = $this->get_cache_token_userid($token);
        if (empty($userId)){
            return null;
        }
        $key = $this->userActiveSet . date("Ymd");
        Redis::SADD($key, $userId);
        Redis::EXPIRE($key, 7*24*3600);
    }

    /**
     * 记录用户tdid
     */
    public function saveUserTdid($tdid=''){
        if (empty($tdid)){
            return null;
        }
        $token = $this->get_cookies_token();
        if (empty($token)){
            return null;
        }
        // 缓存读取
        $userId = $this->get_cache_token_userid($token);
        if (empty($userId)){
            return null;
        }
        $key = $this->userTdidKey;
        Redis::HSET($key, $userId, $tdid);
        Redis::EXPIRE($key, 7*24*3600);
    }

    /**
     * 记录用户tdid
     */
    public function saveUserIdTdid($userId='', $tdid=''){
        if (empty($tdid) || empty($userId)){
            return null;
        }
        $key = $this->userTdidKey;
        Redis::HSET($key, $userId, $tdid);
        Redis::EXPIRE($key, 7*24*3600);
    }

    /**
     * 获取用户tdid
     */
    public function getUserTdid($userId){
        if(empty($userId)) {
            return '';
        }
        $key = $this->userTdidKey;
        $tdid = Redis::HGET($key, $userId);
        if (empty($tdid)){
            return '';
        }
        return $tdid;
    }

    /**
     * 设置用户融云token
     */
    public function setUserRongToken($userId, $token){
        $key = $this->userRongTokenKey . $userId;
        Redis::SET($key, $token, 'EX', 30*86400);
        return true;
    }

    /**
     * 获取用户融云token
     */
    public function getUserRongToken($userId){
        $key = $this->userRongTokenKey . $userId;
        $ret = Redis::GET($key);
        if ($ret == null){
            return null;
        }
        return $ret;
    }

    //交友聊天资料审核状态
    public function getChatFriendVerify($user_id){
        $res = DB::table($this->chat_friend_baseinfo_table)->where(['user_id'=>$user_id])->first();
        $res = $this->objToArray($res);
        return $res;
    }

    //更改交友聊天资料审核状态
    public function changeStatus($id,$status){
        $res = DB::table($this->chat_friend_baseinfo_table)->where('id',$id)->update(['status'=>$status]);
        return $res;
    }

    /**
     * 根据用户ID获取用户每日聊天条数记录
     */
    public function getUserMsg($where)
    {
        $result = DB::table($this->userMsgTable)
            ->where($where)
            ->first();
        if(empty($result)) {
            return [];
        }

        return self::objToArray($result);
    }

    /**
     * 新增用户每日聊天条数记录
     */
    public function createUserMsg($data)
    {
        if(empty($data)) {
            return false;
        }
        $res = DB::table($this->userMsgTable)->insertGetId($data);

        return $res;
    }

    /**
     * 累加用户每日聊天条数记录
     */
    public function incrUserMsg($id, $field, $num)
    {
        if(empty($id)) {
            return false;
        }
        if($num < 1) {
            return false;
        }
        $res = DB::table($this->userMsgTable)->where('id', $id)->increment($field, $num);

        return $res;
    }

    /**
     * 指定公会主播私信统计列表
     */
    public function unionUserMsgStatList($page, $limit, $unionId, $dateSt, $dateEd, $userId=0)
    {
        $query = DB::table($this->userMsgTable)
            ->where('union_id', $unionId);
        if(!empty($dateSt)) {
            $query = $query->where('ymd', '>=', $dateSt);
        }
        if(!empty($dateEd)) {
            $query = $query->where('ymd', '<=', $dateEd);
        }
        if(!empty($userId)) {
            $query = $query->where('from_user_id', $userId);
        }
        //全部用户的
        $data = $query->selectRaw('from_user_id, sum(sms_num) as sms_num, count(DISTINCT to_user_id) as user_num')
            ->groupBy('from_user_id')
            ->paginate($limit, ['*'], 'page', $page);
        $data = $this->objToArray($data);

        $list = [];
        if(!empty($data['data'])) {
            //对新用户的数据
            $userIds = array_column($data['data'], 'from_user_id');
            $data2 = $query->where('if_new', 1)->whereIn('from_user_id', $userIds)->selectRaw('from_user_id, sum(sms_num) as sms_num, count(DISTINCT to_user_id) as user_num')
                ->groupBy('from_user_id')
                ->get();
            $data2 = $this->objToArray($data2);
            $data2 = array_column($data2, null, 'from_user_id');

            foreach($data['data'] as $val) {
                $val['new_use_num'] = empty($data2[$val['from_user_id']]['user_num']) ? 0 :$data2[$val['from_user_id']]['user_num'];
                $val['new_sms_num'] = empty($data2[$val['from_user_id']]['sms_num']) ? 0 :$data2[$val['from_user_id']]['sms_num'];
                $list[] = $val;
            }
        }

        return $list;
    }

    /**
     * 指定公会主播私信统计列表全部数据
     */
    public function getUnionUserMsgStatAll($unionId, $dateSt, $dateEd, $userId=0)
    {
        $query = DB::table($this->userMsgTable)
            ->where('union_id', $unionId);
        if(!empty($dateSt)) {
            $query = $query->where('ymd', '>=', $dateSt);
        }
        if(!empty($dateEd)) {
            $query = $query->where('ymd', '<=', $dateEd);
        }
        if(!empty($userId)) {
            $query = $query->where('from_user_id', $userId);
        }
        //全部用户的
        $data = $query->selectRaw('from_user_id, sum(sms_num) as sms_num, count(DISTINCT to_user_id) as user_num')
            ->groupBy('from_user_id')
            ->get();
        $data = $this->objToArray($data);

        $list = [];
        if(!empty($data)) {
            $userIds = array_column($data, 'from_user_id');
            $usersMap = $this->get_users_by_ids($userIds);
            $usersMap = array_column($usersMap, null, 'user_id');

            //对新用户的数据
            $userIds = array_column($data, 'from_user_id');
            $data2 = $query->where('if_new', 1)->whereIn('from_user_id', $userIds)->selectRaw('from_user_id, sum(sms_num) as sms_num, count(DISTINCT to_user_id) as user_num')
                ->groupBy('from_user_id')
                ->get();
            $data2 = $this->objToArray($data2);
            $data2 = array_column($data2, null, 'from_user_id');

            foreach($data as $val) {
                $val['new_use_num'] = empty($data2[$val['from_user_id']]['user_num']) ? 0 :$data2[$val['from_user_id']]['user_num'];
                $val['new_sms_num'] = empty($data2[$val['from_user_id']]['sms_num']) ? 0 :$data2[$val['from_user_id']]['sms_num'];

                $val['uuid'] = empty($usersMap[$val['from_user_id']]['user_uid']) ? '' : $usersMap[$val['from_user_id']]['user_uid'];
                $val['nickname'] = empty($usersMap[$val['from_user_id']]['nickname']) ? '' : $usersMap[$val['from_user_id']]['nickname'];
                $val['image'] = build_image(empty($usersMap[$val['from_user_id']]['images'][0]) ? '' : $usersMap[$val['from_user_id']]['images'][0]);

                $list[] = $val;
            }
        }

        return $list;
    }

    /**
     * 新增用户异步导出数据明细表
     */
    public function createUserExcelLog($data)
    {
        if(empty($data)) {
            return false;
        }
        $res = DB::table($this->userExcelLogTable)->insertGetId($data);

        return $res;
    }

    /**
     * 获取用户异步导出数据明细列表
     */
    public function getUserExcelLogList($page, $limit, $userId, $type)
    {
        $data = DB::table($this->userExcelLogTable)
            ->where('user_id', $userId)
            ->where('type', $type)
            ->orderBy('id', 'desc')
            ->paginate($limit, ['*'], 'page', $page);
        $data = $this->objToArray($data);
        $list = $data['data'];

        return $list;
    }

    /**
     * 获取未处理的用户异步导出数据明细列表
     */
    public function getUserExcelLogListByStatus($status)
    {
        $data = DB::table($this->userExcelLogTable)
            ->where('status', $status)
            ->get();
        $data = $this->objToArray($data);

        return $data;
    }
    /**
     * 更新用户异步导出数据明细
     */
    public function updateUserExcelLog($id, $url){
        $result = DB::table($this->userExcelLogTable)
            ->where("id", $id)
            ->update(['status'=>1, 'exec_url'=>$url]);
        return $result;
    }
    /**
     * 获取用户注册时间
     */
    public function get_usercreattime($userId){
        $result = DB::table($this->table)
            ->where("user_id", $userId)
            ->first(['create_timestamp']);
        $data = objToArray($result);
        return $data['create_timestamp'];
    }
    /**
     * 获取用户流水
     */
    public function getGiftData($userId){
        $result = DB::table('gift_stream')
            ->selectRaw(DB::raw('SUM(gift_num * gift_price) as total'))
            ->where("from_user_id", $userId)
            ->first(['total']);
        $data = objToArray($result);
        return $data['total'];
    }

    /**
     * 更新用户首冲礼包展示开关
     * @param $userId
     * @param $status
     * @return mixed
     */
    public function updateFirstRechargeStatus($userId,$status)
    {
        return DB::table($this->table)->where(["user_id" => $userId])->update(["first_recharge_status" => $status]);
    }
} 
